package com.study.tx.mixture.service;

import com.alibaba.fastjson2.JSON;
import com.study.tx.common.utils.ApplicationContextUtils;
import com.study.tx.common.dao.OrderItemDao;
import com.study.tx.common.entity.*;
import com.study.tx.common.service.OrderItemService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import javax.annotation.Resource;
import java.math.BigDecimal;

/**
 * 订单项接口的实现
 *
 * @author doveylovey
 * @version v1.0.0
 * @email 1135782208@qq.com
 * @date 2021年02月02日
 */
@Slf4j
@Service("mixtureOrderItemService")
public class MixtureOrderItemServiceImpl implements OrderItemService {
    @Resource
    private OrderItemDao mixtureOrderItemDao;

    @Override
    public Integer truncateOrderItem() {
        int truncateOrderItem = mixtureOrderItemDao.truncateOrderItem();
        log.info("清空 t_order_item 表结果：{}", truncateOrderItem);
        return truncateOrderItem;
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    @Override
    public Integer insert(Order order, Long productId) {
        OrderItem orderItem = new OrderItem();
        orderItem.setOrderId(order.getOrderId());
        orderItem.setUserId(order.getUserId());
        orderItem.setProductId(productId);
        orderItem.setProductName("商品名称-" + productId);
        orderItem.setProductPrice(BigDecimal.ONE);
        orderItem.setPurchaseCount(10);
        orderItem.setPayMoney(BigDecimal.TEN);
        /*if (true) {
            throw new RuntimeException("操作 t_order_item 之前抛出了异常！");
        }*/
        int result = mixtureOrderItemDao.insert(orderItem);
        System.out.println("操作 t_order_item 结果：" + result);
        /*if (true) {
            throw new RuntimeException("操作 t_order_item 之后抛出了异常！");
        }*/
        // 发送消息到 MQ
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
            @Override
            public void beforeCommit(boolean readOnly) {
                log.info("调用了 beforeCommit() 方法，readOnly={}，参数：{}", readOnly, JSON.toJSONString(orderItem));
            }

            @Override
            public void afterCommit() {
                // 当数据成功保存到数据库中并且事务提交了，就发送消息到 MQ 中
                log.info("调用了 afterCommit() 方法，参数：{}", JSON.toJSONString(orderItem));
            }

            @Override
            public void beforeCompletion() {
                log.info("调用了 beforeCompletion() 方法，参数：{}", JSON.toJSONString(orderItem));
            }

            @Override
            public void afterCompletion(int status) {
                log.info("调用了 afterCompletion() 方法，status={}，参数：{}", status, JSON.toJSONString(orderItem));
            }
        });
        // 发布一个自定义的事件
        ApplicationContextUtils.applicationContext.publishEvent(new MyOrderItemTransactionEvent("操作 t_order_item 的事务事件，请事务提交后执行我~~~", orderItem));
        if (productId == null) {
            // 如果代码未发生异常，由于业务不满足某条件而需要回滚时，有两种解决方法：抛出自定义异常(常用)、通过编程代码回滚(不常用)
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return result;
    }
}
